import UIKit

// 注册窗口回调
public protocol RegWindowCallback: NSObjectProtocol {
    func onRegWindowOK(_ username: String, password: String, iconIndex: Int)    // 用户单击"确定"按钮事件
}

// 注册窗口
class RegWindow: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UITextFieldDelegate {
    private var mCallback: RegWindowCallback?   // 回调

    /**
     * 必要的构造方法。
     * @param coder 解码器
     */
    public required init?(coder: NSCoder) {
        super.init(coder: coder)
    }
    
    /**
     * 获取表项的数量。
     * @param collectionView    头像列表视图
     * @param section           一个 section 中的表项的数量
     */
    internal func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return Const.ICON_COUNT
    }

    /**
     * 获取表项。
     * @param collectionView    头像列表视图
     * @param indexPath         行号
     * @return 表项
     */
    internal func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        // 获取表项
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: Const.ICON_CELL_NAME, for: indexPath) as! IconCell
        
        // 设置图标
        cell.setIcon(indexPath.row)

        return cell
    }

    /**
     * 获取 section 的数量。
     * @param collectionView    头像列表视图
     * @return section 的数量
     */
    internal func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }

    /**
     * "取消"按钮的单击响应方法。
     */
    @IBAction private func onCancel() {
        navigationController?.popViewController(animated: true)
    }

    /**
     * "确定"按钮的单击响应方法。
     */    
    @IBAction private func onOK() {
        // 检查用户名是否为空
        let editUsername = view.viewWithTag(Const.TAG_EDIT_USERNAME) as! UITextField
        if editUsername.text == nil || editUsername.text!.isEmpty {
            let title = NSLocalizedString("IDS_USERNAME_EMPTY", tableName: "Main", comment: "")
            Toast.makeText(view, text: title, duration: Toast.LENGTH_LONG).show()
            return
        }
        
        // 检查密码是否为空
        let editPassword = view.viewWithTag(Const.TAG_EDIT_PASSWORD) as! UITextField
        if editPassword.text == nil || editPassword.text!.isEmpty {
            let title = NSLocalizedString("IDS_PASSWORD_EMPTY", tableName: "Main", comment: "")
            Toast.makeText(view, text: title, duration: Toast.LENGTH_LONG).show()
            return
        }
        
        // 检查两次密码是否一致
        let editRepassword = view.viewWithTag(Const.TAG_EDIT_REPASSWORD) as! UITextField
        if editPassword.text != editRepassword.text {
            let title = NSLocalizedString("IDS_PASSWORD_NOT_EQUAL", tableName: "Main", comment: "")
            Toast.makeText(view, text: title, duration: Toast.LENGTH_LONG).show()
            return
        }
        
        // 检查头像索引
        let listViewIcons = view.viewWithTag(Const.TAG_LSIT_VIEW_ICONS) as! UICollectionView
        if listViewIcons.indexPathsForSelectedItems!.isEmpty {
            let text = NSLocalizedString("IDS_ICON_NOT_SELECT", tableName: "Main", comment: "")
            Toast.makeText(view, text: text, duration: Toast.LENGTH_LONG).show()
            return
        }
        let iconIndex = listViewIcons.indexPathsForSelectedItems![0].row

        // 调用回调
        mCallback!.onRegWindowOK(editUsername.text!, password: editPassword.text!, iconIndex: iconIndex)

        // 关闭
        navigationController?.popViewController(animated: true)
    }

    /**
     * 设置回调。
     * @param callback  回调
     */
    public func setCallback(_ callback: RegWindowCallback) {
        mCallback = callback
    }
    
    /**
     * 设置编辑框最大输入长度。
     * @param textField 编辑框
     * @param range     ?
     * @param string    ?
     * @return 不超过最大长度则返回 true，否则返回 false
     */
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        let text = textField.text!
        let len = text.count + string.count - range.length
        if textField.tag == Const.TAG_EDIT_USERNAME {
            return len <= Const.MAX_USERNAME_LEN
        }
        return len <= Const.MAX_PASSWORD_LEN
    }
    
    /**
     * 视图加载事件的响应方法。
     */
    internal override func viewDidLoad() {
        super.viewDidLoad()

        // 设置标题
        title = NSLocalizedString("IDS_REG", tableName: "Main", comment: "")
        
        // 获取控件
        let labelUsername = view.viewWithTag(Const.TAG_LABEL_USERNAME)!
        let editUsername = view.viewWithTag(Const.TAG_EDIT_USERNAME) as! UITextField
        let labelPassword = view.viewWithTag(Const.TAG_LABEL_PASSWORD)!
        let editPassword = view.viewWithTag(Const.TAG_EDIT_PASSWORD) as! UITextField
        let labelRepassword = view.viewWithTag(Const.TAG_LABEL_REPASSWORD)!
        let editRepassword = view.viewWithTag(Const.TAG_EDIT_REPASSWORD) as! UITextField
        let labelUserIcon = view.viewWithTag(Const.TAG_LABEL_USER_ICON)!
        let listViewIcons = view.viewWithTag(Const.TAG_LSIT_VIEW_ICONS) as! UICollectionView
        let buttonOK = view.viewWithTag(Const.TAG_BUTTON_OK)!
        let buttonCancel = view.viewWithTag(Const.TAG_BUTTON_CANCEL)!

        // 设置编辑框代理
        editUsername.delegate = self
        editPassword.delegate = self
        editRepassword.delegate = self
        
        // 设置图标列表控件
        listViewIcons.dataSource = self
        listViewIcons.delegate = self
        let cellXIB = UINib.init(nibName: "IconCell", bundle: Bundle.main)
        listViewIcons.register(cellXIB, forCellWithReuseIdentifier: Const.ICON_CELL_NAME)
        listViewIcons.allowsSelection = true
        
        // 禁用 translatesAutoresizingMaskIntoConstraints，否则控件约束将无效
        labelUsername.translatesAutoresizingMaskIntoConstraints = false
        editUsername.translatesAutoresizingMaskIntoConstraints = false
        labelPassword.translatesAutoresizingMaskIntoConstraints = false
        editPassword.translatesAutoresizingMaskIntoConstraints = false
        labelRepassword.translatesAutoresizingMaskIntoConstraints = false
        editRepassword.translatesAutoresizingMaskIntoConstraints = false
        labelUserIcon.translatesAutoresizingMaskIntoConstraints = false
        buttonOK.translatesAutoresizingMaskIntoConstraints = false
        buttonCancel.translatesAutoresizingMaskIntoConstraints = false

        // 获取屏幕尺寸
        let screenWidth = UIScreen.main.bounds.width
        let screenHeight = UIScreen.main.bounds.height
        let screenY = (navigationController?.navigationBar.frame.height)! + UIApplication.shared.windows.first!.windowScene!.statusBarManager!.statusBarFrame.height

        // 计算控件尺寸
        let paddingH = screenWidth * Const.SCALE_REG_WINDOW_PADDING
        let paddingV = paddingH * 1.2
        let lblWidth = screenWidth - editRepassword.frame.width + paddingH * 3
        let btnCancelLeft = screenWidth / 2 - buttonOK.frame.width - paddingH / 2
        let btnOKLeft = screenWidth / 2 + paddingH / 2

        // 添加控件约束
        /* "用户名"标签 */
        let lcLabelUsernameLeft = NSLayoutConstraint(item: labelUsername, attribute: .left, relatedBy: .equal, toItem: view, attribute: .left, multiplier: 1.0, constant: paddingH)
        view.addConstraint(lcLabelUsernameLeft)

        let lcLabelUsernameTop = NSLayoutConstraint(item: labelUsername, attribute: .top, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1.0, constant: screenY + paddingV)
        view.addConstraint(lcLabelUsernameTop)

        /* "密码"标签 */
        let lcLabelPasswordLeft = NSLayoutConstraint(item: labelPassword, attribute: .left, relatedBy: .equal, toItem: view, attribute: .left, multiplier: 1.0, constant: paddingH)
        view.addConstraint(lcLabelPasswordLeft)

        let lcLabelPasswordTop = NSLayoutConstraint(item: labelPassword, attribute: .top, relatedBy: .equal, toItem: labelUsername, attribute: .bottom, multiplier: 1.0, constant: paddingV)
        view.addConstraint(lcLabelPasswordTop)

        /* "确认密码"标签 */
        let lcLabelRepasswordLeft = NSLayoutConstraint(item: labelRepassword, attribute: .left, relatedBy: .equal, toItem: view, attribute: .left, multiplier: 1.0, constant: paddingH)
        view.addConstraint(lcLabelRepasswordLeft)

        let lcLabelRepasswordTop = NSLayoutConstraint(item: labelRepassword, attribute: .top, relatedBy: .equal, toItem: labelPassword, attribute: .bottom, multiplier: 1.0, constant: paddingV)
        view.addConstraint(lcLabelRepasswordTop)

        /* "用户名"编辑框 */
        let lcEditUsernameRight = NSLayoutConstraint(item: editUsername, attribute: .right, relatedBy: .equal, toItem: view, attribute: .right, multiplier: 1.0, constant: -paddingH)
        view.addConstraint(lcEditUsernameRight)

        let lcEditUsernameCenterY = NSLayoutConstraint(item: editUsername, attribute: .centerY, relatedBy: .equal, toItem: labelUsername, attribute: .centerY, multiplier: 1.0, constant: 0)
        view.addConstraint(lcEditUsernameCenterY)

        let lcEditUsernameWidth = NSLayoutConstraint(item: editUsername, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: lblWidth)
        view.addConstraint(lcEditUsernameWidth)
        
        /* "密码"编辑框 */
        let lcEditPasswordRight = NSLayoutConstraint(item: editPassword, attribute: .right, relatedBy: .equal, toItem: view, attribute: .right, multiplier: 1.0, constant: -paddingH)
        view.addConstraint(lcEditPasswordRight)

        let lcEditPasswordCenterY = NSLayoutConstraint(item: editPassword, attribute: .centerY, relatedBy: .equal, toItem: labelPassword, attribute: .centerY, multiplier: 1.0, constant: 0)
        view.addConstraint(lcEditPasswordCenterY)
        
        let lcEditPasswordWidth = NSLayoutConstraint(item: editPassword, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: lblWidth)
        view.addConstraint(lcEditPasswordWidth)

        /* "确认密码"编辑框 */
        let lcEditRepasswordRight = NSLayoutConstraint(item: editRepassword, attribute: .right, relatedBy: .equal, toItem: view, attribute: .right, multiplier: 1.0, constant: -paddingH)
        view.addConstraint(lcEditRepasswordRight)

        let lcEditRepasswordCenterY = NSLayoutConstraint(item: editRepassword, attribute: .centerY, relatedBy: .equal, toItem: labelRepassword, attribute: .centerY, multiplier: 1.0, constant: 0)
        view.addConstraint(lcEditRepasswordCenterY)
        
        let lcEditRepasswordWidth = NSLayoutConstraint(item: editRepassword, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: lblWidth)
        view.addConstraint(lcEditRepasswordWidth)
        
        /* "用户头像"标签 */
        let lcLabelUserIconLeft = NSLayoutConstraint(item: labelUserIcon, attribute: .left, relatedBy: .equal, toItem: view, attribute: .left, multiplier: 1.0, constant: paddingH)
        view.addConstraint(lcLabelUserIconLeft)

        let lcLabelUserIconTop = NSLayoutConstraint(item: labelUserIcon, attribute: .top, relatedBy: .equal, toItem: labelRepassword, attribute: .bottom, multiplier: 1.0, constant: paddingV)
        view.addConstraint(lcLabelUserIconTop)

        /* "确定"按钮 */
        let lcButtonCancelLeft = NSLayoutConstraint(item: buttonCancel, attribute: .left, relatedBy: .equal, toItem: view, attribute: .left, multiplier: 1.0, constant: btnCancelLeft)
        view.addConstraint(lcButtonCancelLeft)

        let lcButtonCancelBottom = NSLayoutConstraint(item: buttonCancel, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1.0, constant: -paddingV)
        view.addConstraint(lcButtonCancelBottom)

        /* "取消"按钮 */
        let lcButtonOKLeft = NSLayoutConstraint(item: buttonOK, attribute: .left, relatedBy: .equal, toItem: view, attribute: .left, multiplier: 1.0, constant: btnOKLeft)
        view.addConstraint(lcButtonOKLeft)

        let lcButtonOKBottom = NSLayoutConstraint(item: buttonOK, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1.0, constant: -paddingV)
        view.addConstraint(lcButtonOKBottom)

        /* 头像列表 */
        let iconListX = paddingH
        let iconListY = screenY + editUsername.frame.height * 4 + paddingV * 2
        let iconListWidth = screenWidth - paddingH * 2
        let iconListHeight = screenHeight - screenY - editUsername.frame.height * 4 - buttonOK.frame.height - paddingV * 4
        listViewIcons.frame = CGRect(x: iconListX, y: iconListY, width: iconListWidth, height: iconListHeight)
        let layout = UICollectionViewFlowLayout()
        let iconSize = (screenWidth - Const.REG_WINDOW_ICON_SPACING * (Const.REG_WINDOW_ICON_COLUMNS + 1) - paddingH * 2) / Const.REG_WINDOW_ICON_COLUMNS
        layout.itemSize = CGSize(width: iconSize, height: iconSize)
        layout.minimumInteritemSpacing = Const.REG_WINDOW_ICON_SPACING
        layout.minimumLineSpacing = Const.REG_WINDOW_ICON_SPACING
        listViewIcons.collectionViewLayout = layout
    }
}
